﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.LIB;
using YArchitech.Revit;
using YArchitech.Revit.Electric.Common;
using HYRElectric.PowerSystem;

namespace HYRElectric.SystemDiagram
{
	public class SystemDiagramDrawingControler
	{
		public SystemDiagramDrawingControler(ExternalCommandData cmdData)
		{
			this.m_Revit = cmdData;
			this.m_Doc = this.m_Revit.Application.ActiveUIDocument.Document;
		}

		public Result Drawing(List<string> systemInfos, BusInfo busInfo, LoopCommonInfo loopCommonInfo, List<LoopInfo> loopInfo, List<CellInfo> cells)
		{
			bool firstShow = false;
			ViewDrafting draftingView = this.GetDraftingView(ref firstShow);
			this.RefreshView(draftingView, firstShow);
			SystemGraphSet systemGraphSet = null;
			if (!this.ReadSystemDiagramSetting(ref systemGraphSet))
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			GraphicsStyle generatrixStyle = null;
			GraphicsStyle circuitLineStyle = null;
			GraphicsStyle fractionLineStyle = null;
			this.GetLineStyle(systemGraphSet, ref generatrixStyle, ref circuitLineStyle, ref fractionLineStyle);
			TextNoteType textNoteType = null;
			this.GetTextNoteType(systemGraphSet, ref textNoteType);
			return new SystemDiagramDrawingKit(this.m_Revit, this.m_ViewScale, this.m_SwitchLegendColor, generatrixStyle, circuitLineStyle, fractionLineStyle, textNoteType).Drawing(systemGraphSet, systemInfos, busInfo, loopCommonInfo, loopInfo, cells);
		}

		private void RefreshView(ViewDrafting draftingView, bool firstShow)
		{
			try
			{
				if (this.m_Revit.Application.ActiveUIDocument.ActiveView.Id.IntegerValue != draftingView.Id.IntegerValue)
				{
					this.m_Revit.Application.ActiveUIDocument.ActiveView = draftingView;
					UIDocument activeUIDocument = this.m_Revit.Application.ActiveUIDocument;
					activeUIDocument.RefreshActiveView();
					if (firstShow)
					{
						UIView uiview = null;
						foreach (UIView uiview2 in activeUIDocument.GetOpenUIViews())
						{
							if (uiview2.ViewId.Equals(activeUIDocument.ActiveView.Id))
							{
								uiview = uiview2;
								break;
							}
						}
						if (uiview != null)
						{
							XYZ xyz = new XYZ(-100.0, -100.0, -5.0);
							XYZ xyz2 = new XYZ(100.0, 100.0, 5.0);
							uiview.ZoomAndCenterRectangle(xyz, xyz2);
						}
					}
				}
			}
			catch (Exception)
			{
			}
		}

		private ViewDrafting GetDraftingView(ref bool firstShow)
		{
			ViewDrafting viewDrafting = null;
			foreach (Element element in RevitFilter.GetElementsOfType(this.m_Doc, typeof(ViewDrafting)).OfCategory(BuiltInCategory.OST_Views).ToList<Element>())
			{
				if (element.Name.CompareTo("电气系统图") == 0)
				{
					viewDrafting = (element as ViewDrafting);
					this.m_ViewScale = viewDrafting.Scale;
					firstShow = false;
					return viewDrafting;
				}
			}
			if (viewDrafting == null)
			{
				if (!this.CreateViewDrafting(out viewDrafting))
				{
					firstShow = false;
					return viewDrafting;
				}
				Transaction transaction = new Transaction(this.m_Doc);
				transaction.Start("write extensibleStorage");
				viewDrafting.Name = "电气系统图";
				transaction.Commit();
			}
			firstShow = true;
			return viewDrafting;
		}

		private bool CreateViewDrafting(out ViewDrafting view)
		{
			Transaction transaction = new Transaction(this.m_Doc);
			transaction.Start("CreateViewDrafting");
			view = RevitViewExtension.CreateViewDrafting(this.m_Doc);
			if (view == null)
			{
				MessageBox.Show("创建绘图视图失败！");
				transaction.RollBack();
				return false;
			}
			BoundingBoxXYZ boundingBoxXYZ = new BoundingBoxXYZ();
			boundingBoxXYZ.Max = new XYZ(100.0, 100.0, 5.0);
			boundingBoxXYZ.Min = new XYZ(-100.0, -100.0, -5.0);
			view.CropBox = boundingBoxXYZ;
			view.Scale = this.m_ViewScale;
			view.ApplyViewTemplateParameters(this.m_Doc.ActiveView);
			view.get_Parameter(BuiltInParameter.VIEW_NAME).Set("盈建科电气系统图");
			transaction.Commit();
			return true;
		}

		private bool ReadSystemDiagramSetting(ref SystemGraphSet systemGraphSet)
		{
			string path = Path.Combine(Product.WorkingLocation, "SystemGraphSet.xml");
			if (!File.Exists(path))
			{
				string text = "SystemGraphSet.xml";
				string sourceFileName = AssistFunc.GetAppRootPath() + "\\Data\\ElectricalData\\" + text;
				string destFileName = Product.WorkingLocation + text;
				this.CopyFile(sourceFileName, destFileName);
			}
			ExportSystemXML exportSystemXML = new ExportSystemXML(path);
			systemGraphSet = exportSystemXML.LoadCSystemGraphSet(this.m_ViewScale);
			if (systemGraphSet == null)
			{
				MessageBox.Show("读取系统图设置数据出错！");
				return false;
			}
			return true;
		}

		private void CopyFile(string sourceFileName, string destFileName)
		{
			try
			{
				File.Copy(sourceFileName, destFileName);
			}
			catch (Exception)
			{
			}
		}

		private bool GetLineStyle(SystemGraphSet systemGraphSet, ref GraphicsStyle generatrixStyle, ref GraphicsStyle circuitLineStyle, ref GraphicsStyle fractionLineStyle)
		{
			Category category = this.m_Doc.Settings.Categories.get_Item(BuiltInCategory.OST_Lines);
			if (category == null)
			{
				return false;
			}
			string text = "FractionLine " + systemGraphSet.WireWidth.ToString("f0");
			string text2 = "Generatrix " + systemGraphSet.BusWidth.ToString("f0");
			string text3 = "CircuitLine " + systemGraphSet.WireWidth.ToString("f0");
			if (!category.SubCategories.Contains(text2))
			{
				if (!this.CreateLineStyle((int)systemGraphSet.BusWidth, text2, ref category))
				{
					return false;
				}
			}
			else
			{
				Category category2 = category.SubCategories.get_Item(text2);
				Transaction transaction = new Transaction(this.m_Doc);
				transaction.Start("change parameter");
				category2.LineColor = this.m_GeneratrixColor;
				category2.SetLineWeight((int)systemGraphSet.BusWidth, (Autodesk.Revit.DB.GraphicsStyleType)1);
				transaction.Commit();
			}
			if (!category.SubCategories.Contains(text))
			{
				if (!this.CreateLineStyle((int)systemGraphSet.WireWidth, text, ref category))
				{
					return false;
				}
			}
			else
			{
				Category category3 = category.SubCategories.get_Item(text);
				Transaction transaction2 = new Transaction(this.m_Doc);
				transaction2.Start("change parameter");
				category3.LineColor = this.m_FractionColor;
				category3.SetLineWeight((int)systemGraphSet.WireWidth, (Autodesk.Revit.DB.GraphicsStyleType)1);
				transaction2.Commit();
			}
			if (!category.SubCategories.Contains(text3))
			{
				if (!this.CreateLineStyle((int)systemGraphSet.WireWidth, text3, ref category))
				{
					return false;
				}
			}
			else
			{
				Category category4 = category.SubCategories.get_Item(text3);
				Transaction transaction3 = new Transaction(this.m_Doc);
				transaction3.Start("change parameter");
				category4.LineColor = this.m_CircuitColor;
				category4.SetLineWeight((int)systemGraphSet.WireWidth, (Autodesk.Revit.DB.GraphicsStyleType)1);
				transaction3.Commit();
			}
			foreach (Element element in new FilteredElementCollector(this.m_Doc).OfClass(typeof(GraphicsStyle)))
			{
				GraphicsStyle graphicsStyle = element as GraphicsStyle;
				if (graphicsStyle != null)
				{
					if (graphicsStyle.Name.CompareTo(text2) == 0)
					{
						generatrixStyle = graphicsStyle;
					}
					if (graphicsStyle.Name.CompareTo(text3) == 0)
					{
						circuitLineStyle = graphicsStyle;
					}
					if (graphicsStyle.Name.CompareTo(text) == 0)
					{
						fractionLineStyle = graphicsStyle;
					}
				}
			}
			return generatrixStyle != null && circuitLineStyle != null;
		}

		private bool CreateLineStyle(int lineWidth, string typeName, ref Category lineCategory)
		{
			Transaction transaction = new Transaction(this.m_Doc);
			bool result;
			try
			{
				transaction.Start("new line style");
				Category category = this.m_Doc.Settings.Categories.NewSubcategory(lineCategory, typeName);
				if (typeName.IndexOf("Generatrix") != -1)
				{
					category.LineColor = this.m_GeneratrixColor;
					category.SetLineWeight(lineWidth, (Autodesk.Revit.DB.GraphicsStyleType)1);
				}
				else if (typeName.IndexOf("FractionLine") != -1)
				{
					category.LineColor = this.m_FractionColor;
					category.SetLineWeight(lineWidth, (Autodesk.Revit.DB.GraphicsStyleType)1);
				}
				else
				{
					category.LineColor = this.m_CircuitColor;
					category.SetLineWeight(lineWidth, (Autodesk.Revit.DB.GraphicsStyleType)1);
				}
				transaction.Commit();
				result = true;
			}
			catch (Exception)
			{
				if (transaction != null && transaction.HasStarted() && !transaction.HasEnded())
				{
					transaction.RollBack();
				}
				result = false;
			}
			return result;
		}

		private bool GetTextNoteType(SystemGraphSet systemGraphSet, ref TextNoteType textNoteType)
		{
			double num = AssistFunc.mmToFeet(systemGraphSet.TextHeight);
			double num2 = 0.7;
			TextNoteType textNoteType2 = null;
			TextNoteType textNoteType3 = null;
			foreach (Element element in new FilteredElementCollector(this.m_Doc).OfClass(typeof(TextNoteType)).ToElements())
			{
				TextNoteType textNoteType4 = element as TextNoteType;
				if (textNoteType4 != null)
				{
					if (textNoteType3 == null)
					{
						textNoteType3 = textNoteType4;
					}
					else if (textNoteType4.Name.IndexOf("宋体") != -1)
					{
						textNoteType3 = textNoteType4;
					}
					if (textNoteType4.Name.IndexOf("ElectricSystem") > -1)
					{
						Parameter parameter = textNoteType4.get_Parameter(BuiltInParameter.TEXT_SIZE);
						if (parameter != null)
						{
							double d = parameter.AsDouble();
							parameter = textNoteType4.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE);
							if (parameter != null)
							{
								double d2 = parameter.AsDouble();
								parameter = textNoteType4.get_Parameter(BuiltInParameter.LINE_COLOR);
								if (parameter != null)
								{
									int num3 = parameter.AsInteger();
									if (GeoUtil.IsEqual(num, d, 1E-05) && GeoUtil.IsEqual(num2, d2, 1E-05) && num3 == 65280)
									{
										textNoteType = textNoteType4;
										return true;
									}
								}
							}
						}
					}
				}
			}
			if (textNoteType2 != null)
			{
				return true;
			}
			if (textNoteType3 == null)
			{
				return false;
			}
			string text = "ElectricSystem " + AssistFunc.feetToMM(num).ToString("F2") + "mm";
			Transaction transaction = new Transaction(this.m_Doc);
			bool result;
			try
			{
				transaction.Start("new textnote style");
				textNoteType = (textNoteType3.Duplicate(text) as TextNoteType);
				textNoteType.get_Parameter(BuiltInParameter.LINE_COLOR).Set(65280);
				textNoteType.get_Parameter(BuiltInParameter.TEXT_SIZE).Set(num);
				textNoteType.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE).Set(num2);
				transaction.Commit();
				result = true;
			}
			catch (Exception)
			{
				if (transaction != null && transaction.HasStarted() && !transaction.HasEnded())
				{
					transaction.RollBack();
				}
				result = false;
			}
			return result;
		}

		private ExternalCommandData m_Revit;

		private Document m_Doc;

		public const string m_strFractionLineName = "FractionLine";

		public const string m_StrGeneratrixTypeName = "Generatrix";

		public const string m_StrCircuitLineTypeName = "CircuitLine";

		public const string m_StrTextNoteTypeName = "ElectricSystem";

		private int m_ViewScale = 100;

		private Color m_FractionColor = new Color(0, byte.MaxValue, 0);

		private Color m_GeneratrixColor = new Color(byte.MaxValue, 0, byte.MaxValue);

		private Color m_CircuitColor = new Color(0, byte.MaxValue, 0);

		private Color m_SwitchLegendColor = new Color(0, byte.MaxValue, 0);

		private const int m_TextNoteColor = 65280;
	}
}
